namespace CloudNinja.Metering.Providers
{
    using System;
    using System.Diagnostics;

    using CloudNinja.Metering.Data;
    using CloudNinja.Metering.Common;
    using CloudNinja.Metering.Common.Logging;

    public abstract class MeteringProviderBase : IMeteringProvider
    {
        protected readonly ILogger Logger;

        protected readonly IMeteringRepository MeteringRepository;

        protected readonly IMeteringContext MeteringContext;

        private readonly Stopwatch stopwatch;

        protected MeteringProviderBase(TimeSpan collectInterval, IMeteringRepository repository, ILogger logger, IMeteringContext meteringContext)
        {
            Helper.Guard(collectInterval, "collectInterval");
            Helper.Guard(meteringContext, "meteringContext");
            Helper.Guard(logger, "logger");
            Helper.Guard(repository, "repository");

            this.Logger = logger;
            this.MeteringRepository = repository;
            this.MeteringContext = meteringContext;
            this.CollectInterval = collectInterval;
            this.stopwatch = new Stopwatch();
        }

        public TimeSpan CollectInterval { get; private set; }

        public abstract string Name { get; }

        public abstract void Initialize();

        public abstract void Collect();

        public abstract void Stop();

        protected void StartTiming()
        {
            this.stopwatch.Reset();
            this.stopwatch.Start();
            this.Logger.LogInformation(string.Format("Collect called on provider {0} at {1}", this.Name, DateTime.Now));
        }

        protected void StopTiming()
        {
            this.stopwatch.Stop();
            var elapsed = (new TimeSpan(this.stopwatch.ElapsedTicks)).TotalMinutes;

            this.Logger.LogInformation(string.Format("Provider {0} finished collecting data in {1} minutes.", this.Name, elapsed));
        }
    }
}